package com.cell.service.user.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cell.common.States;
import com.cell.common.exceptions.exceptions.UserException;
import com.cell.dao.user.UserLoginAccountDao;
import com.cell.dao.user.location.LocationDetailDao;
import com.cell.dao.user.UserDao;
import com.cell.dao.user.location.UserLocationDao;
import com.cell.pojo.DTO.user.signUpDTO;
import com.cell.pojo.VO.user.NearByAgentVO;
import com.cell.pojo.VO.user.UserDetailVO;
import com.cell.pojo.entity.location.Province;
import com.cell.pojo.entity.user.UserLoginAccount;
import com.cell.pojo.entity.user.UserValidation;
import com.cell.pojo.entity.user.location.LocationDetail;
import com.cell.pojo.entity.user.User;
import com.cell.pojo.entity.user.location.UserLocation;
import com.cell.pojo.entity.user.pointaccount.UserPointAccount;
import com.cell.service.location.ICityService;
import com.cell.service.location.IProvinceService;
import com.cell.service.order.IOrderService;
import com.cell.service.user.IUserLoginAccountService;
import com.cell.service.user.IUserPointAccountService;
import com.cell.service.user.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cell.service.user.IUserValidationService;
import com.cell.utils.UserUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLClientInfoException;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cloudJiang
 * @since 2022-06-04
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements IUserService {
    @Autowired
    UserDao userDao;

    @Autowired
    IUserLoginAccountService loginAccountService;

    @Autowired
    IOrderService orderService;

    @Autowired
    IUserValidationService validationService;

    @Autowired
    UserLocationDao userLocationDao;

    @Autowired
    LocationDetailDao locationDetailDao;

    @Autowired
    IProvinceService provinceService;

    @Autowired
    ICityService cityService;

    @Autowired
    IUserPointAccountService pointAccountService;

    @Autowired
    UserUtil util;
    @Autowired
    UserLoginAccountDao userLoginAccountDao;


    @Override
    public void updateIcon() {

    }

    @Override
    public void updateName(Long userId, String userName) {
        if (userId == null || userName.isEmpty()) {
            throw new UserException(States.ERR_BAD_REQUEST.getStates(), "参数不能为空");
        }
        User user = userDao.selectById(userId);
        if (user == null) {
            throw new UserException(States.ERR_SELECT.getStates(), "查询失败，请检查user_Id是否正确");
        }
        user.setUserName(userName);
        int i = userDao.updateById(user);
        if (i != 1) {
            throw new UserException(States.ERR_UPDATE.getStates(), "更改失败，请稍后再试");
        }
    }

    @Override
    public User getByUserName(String userName) {
        if (userName.isEmpty()) {
            throw new UserException(States.ERR_BAD_REQUEST.getStates(), "参数不能为空");
        }
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("user_name", userName);
        User user = userDao.selectOne(wrapper);
        if (user == null) {
            throw new UserException(States.ERR_USER_NOT_FOUND.getStates(), "用户不存在");
        }
        return user;
    }


    @Override
    @Transactional(rollbackFor = {SQLClientInfoException.class, UserException.class})
    public void signUp(signUpDTO signUpDTO) {
        //先根据邮箱和phone进行判断，查找表中是否已经存在了邮箱和phone，
        //查找电话是否唯一
        QueryWrapper<UserLoginAccount> phonewrapper = new QueryWrapper<>();
        phonewrapper.eq("phone", signUpDTO.getPhone());
        UserLoginAccount userLoginAccount1 = loginAccountService.getOne(phonewrapper);
        System.out.println(userLoginAccount1);
        if (userLoginAccount1 != null) {
            throw new UserException(States.ERR_SELECT.getStates(), "该电话号码已经被注册，请更换号码");
        }

        //插入user_login_account表中数据
        UserLoginAccount userLoginAccount = new UserLoginAccount();
        BeanUtils.copyProperties(signUpDTO, userLoginAccount);
        boolean save = loginAccountService.save(userLoginAccount);
        if (!save) {//表示成功插入第一个表中数据
            throw new UserException(States.ERR_INSERT.getStates(),
                    "插入user_login_account表数据失败，请检查参数，稍后重试");
        }
        //获取省份id
        QueryWrapper<Province> wrapper = new QueryWrapper<>();
        wrapper.eq("name", signUpDTO.getProvinceName());
        Province province = provinceService.getOne(wrapper);
        int provinceId = province.getId();
        //将distrct,community,location_details插入表中
        LocationDetail locationDetail = new LocationDetail();
        BeanUtils.copyProperties(signUpDTO, locationDetail);
        int insert1 = locationDetailDao.insert(locationDetail);
        if (insert1 != 1) {
            throw new UserException(States.ERR_INSERT.getStates(),
                    "插入location_detail表数据失败，请检查参数，稍后重试");
        }
        Long detailId = locationDetail.getId();
        //获得了具体位置id，省份id，城市所在名，插入user_location表中
        UserLocation userLocation = new UserLocation();
        userLocation.setCityName(signUpDTO.getCityname());
        userLocation.setCountryId(1);
        userLocation.setProvinceId(provinceId);
        userLocation.setDetailId(detailId);
        int insert2 = userLocationDao.insert(userLocation);
        if (insert2 != 1) {
            throw new UserException(States.ERR_INSERT.getStates(),
                    "插入user_location表数据失败，请检查参数，稍后再试");
        }
        //判断用户名在表中是否重读
        QueryWrapper<User> usernamewrapper = new QueryWrapper<>();
        usernamewrapper.eq("user_name", signUpDTO.getUserName());
        User users = userDao.selectOne(usernamewrapper);
        if (users != null) {
            throw new UserException(States.ERR_UNIQUE.getStates(), "用户名已经存在");
        }
        //插入一个积分表
        UserPointAccount pointAccount = new UserPointAccount();
        pointAccount.setBalance(0);
        pointAccountService.save(pointAccount);
        //插入一个用户验证相关信息表
        UserValidation validation = new UserValidation();
        validation.setEmailCode("0");
        validation.setPhoneCode("0");
        validationService.save(validation);
        //插入用户表
        User user = new User();
        user.setUserName(signUpDTO.getUserName());
        user.setLoginAccountId(userLoginAccount.getId());
        user.setLocationId(userLocation.getId());
        user.setValidationId(validation.getId());
        user.setPointAccountId(pointAccount.getId());
        int insertUser = userDao.insert(user);
        if (insertUser != 1) {
            throw new UserException(States.ERR_INSERT.getStates(), "插入usr表失败，请检查数据，稍后重试");
        }
    }

    @Override
    public void resetPassword(Long id, String password) {
        if (id == null || password.isEmpty()) {
            throw new UserException(States.ERR_BAD_REQUEST.getStates(), "参数不能为空");
        }
        UserLoginAccount userLoginAccount = loginAccountService.getById(id);
        userLoginAccount.setPassword(util.encryptByMD5(password));
        boolean b = loginAccountService.updateById(userLoginAccount);
        if (!b) {
            throw new UserException(States.ERR_SQL.getStates(), States.ERR_SQL.getDescription());
        }
    }

    @Override
    public UserDetailVO getUserMessage(Long userId) {
        if (userId == null) {
            throw new UserException(States.ERR_USER_NOT_FOUND.getStates(), "用户id不能为空");
        }

        UserDetailVO detailVO = new UserDetailVO();
        User u = this.getById(userId);
        if (u == null) {
            throw new UserException(States.ERR_USER_NOT_FOUND.getStates(), States.ERR_USER_NOT_FOUND.getDescription());
        }

        Long loginAccountId = u.getLoginAccountId();
        Long pointAccountId = u.getPointAccountId();
        Long locationId = u.getLocationId();
        Long detailId = userLocationDao.selectById(locationId).getDetailId();

        UserLocation userLocation = userLocationDao.selectById(locationId);
        LocationDetail locationDetail = locationDetailDao.selectById(detailId);
        String proName = provinceService.getById(userLocation.getProvinceId()).getName();

        detailVO.setName(u.getUserName());
        detailVO.setIconUrl(u.getIconUrl() == null ? "/imgs/userIcon/defult.jpg" : u.getIconUrl());
        detailVO.setEmail(loginAccountService.getEmail(loginAccountId) == null ?
                "暂未绑定邮箱" : loginAccountService.getEmail(loginAccountId));
        detailVO.setPhone(loginAccountService.getPhone(loginAccountId));
        detailVO.setPoint(pointAccountService.getById(pointAccountId).getBalance());
        detailVO.setLocation(proName + userLocation.getCityName() + locationDetail.getDistrict() +
                locationDetail.getCommunity() + locationDetail.getLocationDetails());

        return detailVO;
    }

    @Override
    public List<User> getUsersFromCity(Integer provinceId, String city) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("city_name", city);
        wrapper.eq("province_id", provinceId);
        List<UserLocation> list = userLocationDao.selectList(wrapper);
        List<User> users = new ArrayList<>();

        //获取当前地区下的所有用户
        for (UserLocation location : list) {
            wrapper.clear();
            wrapper.eq("location_id", location.getId());
            users.add(userDao.selectOne(wrapper));
        }
        return users;
    }

    @Override
    public List<User> getUsersFromDetail(Integer provinceId, String city, String district, String community) {
        List<User> usersFromCity = this.getUsersFromCity(provinceId, city);
        List<User> users = new ArrayList<>();

        //二次过滤
        for (User u : usersFromCity) {
            //获取位置细节信息
            LocationDetail locationDetail = locationDetailDao.selectById(userLocationDao.selectById(u.getLocationId()).getDetailId());
            if (locationDetail.getDistrict().equals(district)) {
                if (community.isEmpty()) {
                    users.add(u);
                } else {
                    if (locationDetail.getCommunity().equals(community)) {
                        users.add(u);
                    }
                }
            }
        }

        return users;
    }


    @Override
    public List<User> getCommunityAgentByAdmin(User user) {
        UserLocation userLocation = userLocationDao.selectById(user.getLocationId());
        LocationDetail locationDetail = locationDetailDao.selectById(userLocation.getDetailId());

        return userDao.selectCommunityAgentByAdmin(userLocation.getCountryId(), userLocation.getProvinceId(),
                userLocation.getCityName(), locationDetail.getDistrict(), locationDetail.getCommunity());
    }

    @Override
    public List<NearByAgentVO> getCommunityAgent(Long locationId) {
        /**
         * 通过传进来的user,通过locationid,获取一个userlocation，通过detailid获取具体loc
         */
        if (locationId == null) {
            throw new UserException(States.ERR_BAD_REQUEST.getStates(), "参数不能为空");
        }
        UserLocation userLocation = userLocationDao.selectById(locationId);
        LocationDetail locationDetail = locationDetailDao.selectById(userLocation.getDetailId());
        if (locationDetail == null || userLocation == null) {
            throw new UserException(States.ERR_SELECT.getStates(), "查询失败，请检查给出的id");
        }
        List<User> users = userDao.selectCommunityAgent(userLocation.getCountryId(),
                userLocation.getProvinceId(),
                userLocation.getCityName(),
                locationDetail.getDistrict(),
                locationDetail.getCommunity());
        if (users.isEmpty()) {
            throw new UserException(States.ERR_SELECT.getStates(), "没有查询到当前社区代理，请换一个条件试试");
        }
        NearByAgentVO nearByAgentVO = new NearByAgentVO();
        List<NearByAgentVO> list = new ArrayList<>();
        for (User user : users) {
            nearByAgentVO.setUserName(user.getUserName());
            Long locationId1 = user.getLocationId();
            UserLocation userLocation1 = userLocationDao.selectById(locationId1);
            Long locationDetailId = userLocation1.getDetailId();
            LocationDetail locationDetail1 = locationDetailDao.selectById(locationDetailId);
            String location = locationDetail1.getDistrict() +
                    locationDetail1.getCommunity() +
                    locationDetail1.getLocationDetails();
            nearByAgentVO.setLocation(location);
            Long loginAccountId = user.getLoginAccountId();
            UserLoginAccount userLoginAccount = userLoginAccountDao.selectById(loginAccountId);
            String phone = userLoginAccount.getPhone();
            nearByAgentVO.setPhone(phone);
            list.add(nearByAgentVO);
        }
        return list;
    }
    /*
    String userName;
    String location;
    String phone;
     */

    @Override
    public List<User> getNearbyCommunityAgentByAdmin(Long locationId) {
        UserLocation userLocation = userLocationDao.selectById(locationId);
        LocationDetail locationDetail = locationDetailDao.selectById(userLocation.getDetailId());

        return userDao.selectNearbyCommunityAgentByAdmin(userLocation.getCountryId(), userLocation.getProvinceId(),
                userLocation.getCityName(), locationDetail.getDistrict());
    }

    @Override
    public List<NearByAgentVO> getNearbyCommunityAgent(Long locationId) {
        if (locationId == null) {
            throw new UserException(States.ERR_BAD_REQUEST.getStates(), "参数不能为空");
        }
        UserLocation userLocation = userLocationDao.selectById(locationId);
        LocationDetail locationDetail = locationDetailDao.selectById(userLocation.getDetailId());
        if (locationDetail == null || userLocation == null) {
            throw new UserException(States.ERR_SELECT.getStates(), "查询失败，请检查给出的id");
        }
        List<User> users = userDao.selectNearbyCommunityAgent(userLocation.getCountryId(), userLocation.getProvinceId(),
                userLocation.getCityName(), locationDetail.getDistrict());
        if (users.isEmpty()) {
            throw new UserException(States.ERR_SELECT.getStates(), "没有查询到附近社区代理，请换一个社区试试");
        }
        NearByAgentVO nearByAgentVO = new NearByAgentVO();
        List<NearByAgentVO> list = new ArrayList<>();
        for (User user : users) {
            nearByAgentVO.setUserName(user.getUserName());
            Long locationId1 = user.getLocationId();
            UserLocation userLocation1 = userLocationDao.selectById(locationId1);
            Long locationDetailId = userLocation1.getDetailId();
            LocationDetail locationDetail1 = locationDetailDao.selectById(locationDetailId);
            String location = locationDetail1.getDistrict() +
                    locationDetail1.getCommunity() +
                    locationDetail1.getLocationDetails();
            nearByAgentVO.setLocation(location);
            Long loginAccountId = user.getLoginAccountId();
            UserLoginAccount userLoginAccount = userLoginAccountDao.selectById(loginAccountId);
            String phone = userLoginAccount.getPhone();
            nearByAgentVO.setPhone(phone);
            list.add(nearByAgentVO);
        }
        return list;
    }

    @Override
    public List<User> getNearbyDistrictAgentByAdmin(User user) {
        UserLocation userLocation = userLocationDao.selectById(user.getLocationId());
        LocationDetail locationDetail = locationDetailDao.selectById(userLocation.getDetailId());

        return userDao.selectNearbyDistrictAgentByAdmin(userLocation.getCountryId(), userLocation.getProvinceId(),
                userLocation.getCityName(), locationDetail.getDistrict());
    }

    @Override
    public List<NearByAgentVO> getNearbyDistrictAgent(Long locationId) {
        if (locationId == null) {
            throw new UserException(States.ERR_BAD_REQUEST.getStates(), "参数不能为空");
        }
        UserLocation userLocation = userLocationDao.selectById(locationId);
        LocationDetail locationDetail = locationDetailDao.selectById(userLocation.getDetailId());
        if (userLocation == null || locationDetail == null) {
            throw new UserException(States.ERR_SELECT.getStates(), "查询失败，请检查给出的id");
        }
        List<User> users = userDao.selectNearbyDistrictAgent(userLocation.getCountryId(), userLocation.getProvinceId(),
                userLocation.getCityName(), locationDetail.getDistrict());
        if (users.isEmpty()) {
            throw new UserException(States.ERR_SELECT.getStates(), "当前区域无代理，请换一个条件试试");
        }
        NearByAgentVO nearByAgentVO = new NearByAgentVO();
        List<NearByAgentVO> list = new ArrayList<>();
        for (User user : users) {
            nearByAgentVO.setUserName(user.getUserName());
            Long locationId1 = user.getLocationId();
            UserLocation userLocation1 = userLocationDao.selectById(locationId1);
            Long locationDetailId = userLocation1.getDetailId();
            LocationDetail locationDetail1 = locationDetailDao.selectById(locationDetailId);
            String location = locationDetail1.getDistrict() +
                    locationDetail1.getCommunity() +
                    locationDetail1.getLocationDetails();
            nearByAgentVO.setLocation(location);
            Long loginAccountId = user.getLoginAccountId();
            UserLoginAccount userLoginAccount = userLoginAccountDao.selectById(loginAccountId);
            String phone = userLoginAccount.getPhone();
            nearByAgentVO.setPhone(phone);
            list.add(nearByAgentVO);
            System.out.println(list);
        }
        return list;
    }

    @Override
    public void deleteUserByAdmin(User user) {
        userDao.deleteUserByAdmin(user.getId());
    }

    @Override
    public void deleteUser(Long id) {
        userDao.deleteUser(id);
    }
}
